﻿using System.Linq;

using VSTalk.Engine.Core.EntitySession;
using VSTalk.Engine.Core.Feed;
using VSTalk.Model;

using agsXMPP;

namespace VSTalk.Engine.Core.ChatSession
{
    public class InterlocutorChatSession : IInterlocutorChatSession, IMessageConsumer
    {
        public IInterlocutorResource ActiveResource
        {
            get
            {
                if (InterlocutorContext.Resources.Contains(_activeResource))
                {
                    return _activeResource;
                }
                _activeResource = InitResource();
                return _activeResource;
            }
        }

        public Interlocutor Interlocutor
        {
            get { return _interlocutor; }
        }

        private readonly Interlocutor _interlocutor;
        private IInterlocutorResource _activeResource;

        public static IMessageFeed MessageFeed
        {
            get { return AppServices.Get<IMessageFeed>(); }
        }

        private static ISessionModel SessionModel
        {
            get { return AppServices.Get<ISessionModel>(); }
        }

        public IInterlocutorContext InterlocutorContext
        {
            get { return SessionModel.GetInterlocutorContext(_interlocutor); }
        }

        public InterlocutorChatSession(Interlocutor interlocutor)
        {
            _interlocutor = interlocutor;
            _activeResource = ReadHistory();
        }

        private IInterlocutorResource InitResource()
        {
            if (InterlocutorContext.Resources.Count() == 1)
            {
                return InterlocutorContext.Resources.Single();
            }
            return null;
        }

        private IInterlocutorResource ReadHistory()
        {
            var latest = MessageFeed.GetMessages(Predicate).LastOrDefault();
            if (latest == null)
            {
                _activeResource = InitResource();
                return InitResource();
            }
            var from = latest.XmppMessage.From;
            var resource = InterlocutorContext.Resources.FirstOrDefault(interlocutorResource => Equals(interlocutorResource.Jid, @from));
            return resource;
        }

        public void Consume(IMessage message)
        {
            _activeResource = GetActiveResource(message);
        }

        private IInterlocutorResource GetActiveResource(IMessage message)
        {
            var from = message.XmppMessage.From;
            var resource = InterlocutorContext.Resources.FirstOrDefault(interlocutorResource => Equals(interlocutorResource.Jid, @from));
            if (resource != null)
            {
                return resource;
            }
            return InitResource();
        }

        public bool Predicate(IMessage message)
        {
            return AddressPatterns.From(_interlocutor)(message);
        }
    }
}